package com.henu.acmrating.controller;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.henu.acmrating.common.Result;
import com.henu.acmrating.crawler.BindRun;
import com.henu.acmrating.pojo.Blog;
import com.henu.acmrating.pojo.CfRating;
import com.henu.acmrating.pojo.User;
import com.henu.acmrating.pojo.UserOj;
import com.henu.acmrating.service.BlogService;
import com.henu.acmrating.service.ProblemService;
import com.henu.acmrating.service.UserOjService;
import com.henu.acmrating.service.UserService;
import com.henu.acmrating.utils.FileUtils;
import com.henu.acmrating.utils.HuToolUtils;
import com.henu.acmrating.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Random;

@RestController
@RequestMapping("/api")
public class UserController {

    @Resource
    UserService userService;

    @Resource
    UserOjService userOjService;

    @Resource
    ProblemService problemService;

    @Resource
    BlogService blogService;

    @Value("${prop.upload-folder}")
    private String UPLOAD_FOLDER;

    /**
     * 注册账号
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public Result register(@RequestBody User user) {
        // 1.判断用户名是否存在
        if (user.getUserAccount() == null ||
                userService.selectOneByUserAccount(user.getUserAccount()) != null) {
            return Result.error("注册失败，该账号已存在");
        }
        if(  userService.selectOneByUserEmail(user.getUserEmail()) != null )
            return Result.error("注册失败，该邮箱已存在");
        // 2.保存数据库
        // 加密密码
        user.setUserPassword(HuToolUtils.encrypt(user.getUserPassword()));
        user.setUserImage("/api/img/mm.jpg");
        if (userService.insert(user) == 0) {
            return Result.error("注册失败，非法注册");
        }
        return Result.success("注册成功");
    }

    /**
     * 登陆账号
     */
    @RequestMapping(value = "/login")
    public Result login(@RequestBody User user) {
        user.setUserPassword(HuToolUtils.encrypt(user.getUserPassword()));
        User userDB = userService.selectOneByAll(user);
        user.setUserEmail(user.getUserAccount());
        user.setUserAccount(null);
        User userDB2 = userService.selectOneByAll(user);
        // 1.判断账号密码是否正确
        if (userDB == null && userDB2 == null) {
            return Result.error("账号或密码错误");
        }
        if(userDB == null) userDB = userDB2;
        // 2.通过userId设置token
        String token = JwtUtils.sign(userDB.getUserId() + "");
        userDB.setUserPassword(null);
        JSONObject json = new JSONObject();
        json.put("token", token);
        json.put("user", userDB);
        return Result.success("登陆成功", json);
    }

    /**
     * 更新头像
     */
    @RequestMapping(value = "/uploadImage", method = RequestMethod.POST)
    public Result uploadImage(@RequestParam("file") MultipartFile file, HttpServletRequest request) {

        try {
            String fileName = FileUtils.upload(file, UPLOAD_FOLDER);
            if(fileName == null) {
                return Result.error("文件为空");
            }
            Integer userId = JwtUtils.getUserId(request);
            User user = userService.selectByPrimaryKey(userId);
            user.setUserImage(fileName);
            userService.updateByPrimaryKey(user);
            // 返回图片地址
            return Result.success("更换成功", fileName);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("服务器异常，上传失败");
        }
    }

    /**
     * 添加博客图片
     */
    @RequestMapping(value = "/imgAdd")
    public Result imgAdd(@RequestParam("file") MultipartFile file) {
        try {
            String fileName = FileUtils.upload(file, UPLOAD_FOLDER);
            if(fileName == null) {
                return Result.error("文件为空");
            }
            // 返回图片地址
            return Result.success("更换成功", fileName);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("服务器异常，上传失败");
        }
    }

    /**
     * 更新个人信息
     */
    @RequestMapping(value = "/updateInfo", method = RequestMethod.POST)
    public Result updateInfo(@RequestBody JSONObject json) {

        User user = new User();
        user.setUserAccount(json.getString("userAccount"));
        user.setUserPassword(HuToolUtils.encrypt(json.getString("userPassword")));

        User userDb = userService.selectOneByAll(user);
        if (userDb == null) {
            return Result.error("原密码错误，修改失败");
        }
        userDb.setUserName(json.getString("userName"));
        userDb.setUserRole(json.getInteger("userRole"));
        userDb.setUserMotto(json.getString("userMotto"));
        userDb.setUserSchool(json.getString("userMotto"));
        userDb.setUserSchool(json.getString("userSchool"));
        userDb.setUserGrade(json.getString("userGrade"));
        String newPass = json.getString("newPass");
        if (newPass != null && newPass.length() != 0) {
            userDb.setUserPassword(HuToolUtils.encrypt(newPass));
            userService.updateByPrimaryKeySelective(userDb);
            return Result.success(2, "修改成功，请重新登陆");
        }

        userService.updateByPrimaryKeySelective(userDb);
        userDb.setUserPassword(null);
        return Result.success("修改成功", userDb);
    }


    /**
     * 拿到默认绑定OJ的name
     */
    @RequestMapping(value = "/getOjAccount")
    public Result getOjAccount(HttpServletRequest request) {
        Integer userId = JwtUtils.getUserId(request);
        List<UserOj> userOjs = userOjService.selectByUserId(userId);
        return Result.success(userOjs);
    }

    /**
     * 个人中心
     */
    @RequestMapping(value = "/profile", method = RequestMethod.GET)
    public Result profile(@RequestParam("id") Integer userId) {
        if(userId == null) {
            return Result.error("系统错误");
        }
        User user = userService.selectByPrimaryKey(userId);
        List<UserOj> userOjs = userOjService.selectByUserId(userId);
        List<Blog> blogs = blogService.selectByUserIdAndIsPublic(userId);
        user.setUserPassword(null);
        JSONObject json = new JSONObject();
        json.put("user", user);
        json.put("ojList", userOjs);
        json.put("blogList", blogs);

        return Result.success(json);
    }

    /**
     * 拿到cf排名
     */
    @RequestMapping(value = "/getCfScore", method = RequestMethod.GET)
    public Result getCfScore() {
        List<CfRating> cfRatings = userOjService.selectByCf();
        return Result.success(cfRatings);
    }


    @RequestMapping(value = "/sendVerifyCode", method = RequestMethod.GET)
    public Result sendVerifyCode(@RequestParam("email") String email) {
        User user = userService.selectOneByUserEmail(email);
        if (user == null) return Result.error("邮箱不存在");

        String verifyCode = String
                .valueOf(new Random().nextInt(899999) + 100000);//生成短信验证码

        HuToolUtils.verifyCode(user.getUserEmail(), user.getUserName(), "密码", verifyCode);
        String sign = JwtUtils.sign(verifyCode);

        return Result.success("验证码已发送", sign);
    }

    /**
     * 验证邮箱验证码
     *
     * @param code       本地验证码
     * @param verifyCode 前端验证码
     */
    @RequestMapping(value = "/judgeVerifyCode", method = RequestMethod.GET)
    public Result judgeVerifyCode(@RequestParam("email") String email, @RequestParam("code") String code, @RequestParam("verifyCode") String verifyCode) {
        String vCode = JwtUtils.verity(verifyCode) + "";
        if (code.equals(vCode)) {
            String token = JwtUtils.sign(email);
            return Result.success("", token);
        }
        return Result.error("验证码错误");
    }

    /**
     * 先验证验证码，在修改密码
     *
     * @param json 表单数据
     */
    @RequestMapping(value = "/modifyPassword", method = RequestMethod.POST)
    public Result modifyPassword(@RequestBody JSONObject json) {

        String vCode = JwtUtils.verity(json.getString("verifyCode")) + "";

        if (!json.getString("code").equals(vCode)) return Result.error("验证码错误");

        User userDB = userService.selectOneByUserEmail(json.getString("email"));
        userDB.setUserPassword(HuToolUtils.encrypt(json.getString("password")));
        userService.updateByPrimaryKey(userDB);

        // 设置token， 返回
        String token = JwtUtils.sign(userDB.getUserId() + "");
        userDB.setUserPassword(null);
        JSONObject json1 = new JSONObject();
        json1.put("token", token);
        json1.put("user", userDB);
        return Result.success("修改密码成功，正在跳转", json1);
    }


    /**
     * 绑定OJ账号
     */
    @RequestMapping(value = "/bindOjAccount", method = RequestMethod.POST)
    public Result updateUserOjName(@RequestBody UserOj userOj, HttpServletRequest request) {
        int userId = JwtUtils.getUserId(request);
        String ojName = userOj.getOjName();

        if(userOj.getAccount() == null) {
            return Result.error("绑定失败,账号不能为空");
        }

        UserOj userOjDb = userOjService.selectByAccountAndOjName(userOj.getAccount(), ojName);
        if(userOjDb != null) {
            return Result.error("绑定失败,重复绑定");
        }

        UserOj userOj2 = userOjService.selectByUserIdAndOjName(userId, ojName);

        String msg = "";
        if(userOj2 != null) {
            // 1.把以前的提交记录删掉
            problemService.deleteByUserIdAndOjName(userId, ojName);
            // 2.更新userOj
            userOj2.setAccount(userOj.getAccount());
            userOj2.setLastId(0);
            userOj2.setMaxId(0);
            userOj2.setSolved(0);
            userOj2.setSubmissions(0);
            userOjService.updateByPrimaryKey(userOj2);
            msg = "重新绑定成功，已删除上一个账号的记录";
        } else {
            // 说明是新绑定的
            userOj.setUserId(userId);
            userOj.setLastId(0);
            userOj.setMaxId(0);
            userOj.setSolved(0);
            userOj.setSubmissions(0);
            userOjService.insert(userOj);
            msg = "绑定成功";
        }
        return Result.success(msg);
    }


    @RequestMapping(value = "/crawlerOj")
    public Result crawlerOj(@RequestBody UserOj userOj) {
        String id = userOj.getAccount();
        String ojName = userOj.getOjName();
        if(id != null && ojName != null) {
            BindRun.run(ojName, id);
        }
        return Result.success();
    }

    @RequestMapping(value = "/crawler")
    public Result crawler(@RequestParam("oj") String ojName) {
        BindRun.crawler(ojName);
        return Result.success();
    }


    @GetMapping(value = "/luogu/user/search")
    public Result luoguSearch(@RequestParam("keyword") String keyword) {
        String url = "https://www.luogu.com.cn/api/user/search?keyword="+keyword;
        return Result.success(JSON.parseObject(HttpUtil.get(url)));
    }
}
